package model;

import java.util.*;

import model.semantics.Node;

/**
 * Represents the state of the expression tree. For most of the nodes, the only
 * reason this exists is to pass on to children. However, leaf nodes such as the
 * VariableNode query this class.
 * 
 * @author Sterling Dorminey
 */
public abstract class State<T> {

    private VariableTable<T> myVariableTable;

    public State(T defaultValue) {
        myVariableTable = new VariableTable<T>(defaultValue);
    }

    /**
     * Set the variable table used by the state.
     */
    public void setVariableTable(VariableTable<T> variableTable) {
        myVariableTable = variableTable;
    }

    /**
     * Get the variable table used by the state.
     */
    public VariableTable<T> getVariableTable() {
        return myVariableTable;
    }

    /**
     * Get the reference mapped to the variable. Return a default value if it
     * isn't in the table.
     */
    public Node<T> getAssignment(String variable) {
        return myVariableTable.getAssignment(variable);
    }

    /**
     * Returns a copy of this state.
     */
    public abstract State<T> clone();

    /**
     * Get the default value to return if the variable does not exist in the
     * state.
     */
    public abstract Node<T> getDefaultValue();

    /**
     * Set a variable to map to a reference node.
     */
    public void setAssignment(String variable, Node<T> value) {
        myVariableTable.setAssignment(variable, value);
    }

    /**
     * Get the mapping of state variables to the string formats of the
     * expression. NOTE that the variable table returned is not kept in sync
     * with the current state.
     */
    public Map<String, String> getVariableTableStrings() {
        return myVariableTable.getVariableTable();
    }
}
